﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Npgsql;
using LayerData.DataBaseManager;
using LayerEntity.Ventas;
using System.Collections;
using LayerEntity.Caja;
using System.Data;
using LayerEntity.Sistema;
using LayerEntity.Creditos;

namespace LayerData.Ventas
{
   public class DFacturacion
    {
          #region Variables
        readonly string mensajeExecuteReader = "Error al Recuperar #replace, revise lo Siguiente: ";
        readonly IPostgreSqlConnectionInfo connectionInfo;
        public IPostgreSqlConnectionInfo CurrentConection { get; set; }
        #endregion
        #region Contructores
        public DFacturacion()
        {
            this.connectionInfo = ObjectFactory.CreateConnectionInfo();
        }

        public DFacturacion(IPostgreSqlConnectionInfo con)
        {
            this.connectionInfo = con;
            this.CurrentConection = con;
        }

        #endregion
        #region Operaciones de Grabacion()
        public string[] GetNombres(int num)
        {
            ArrayList nombres = new ArrayList();

            for (int i = 0; i < num; i++)
                nombres.Add("Nombre " + i);

            string[] data = (string[])nombres.ToArray(typeof(string)); 

            return data;
        }
        public object[] MantenimientoGrabarFacturacion(EFacturacion Fact,
                                        EDetFacturacion DFact,
                                        EMovientoCaja Emov,
                                        ECreditos Ecred,
                                        EnumOperaciones operacion)
        {
            object[] Msg = null; ;
            string[] result = null;
            string[] resCred = null; ;
            object[] ResultFac= null ;
            //  ArrayList proc = new ArrayList();
            bool res = false;
            object obj;
            NpgsqlConnection con = null;
            try
            {
                con = this.CurrentConection.GetPostgreSqlConnection();
                NpgsqlTransaction tran = this.CurrentConection.GetTransaction(con);
                /*codigo agregado a la respuesta*/

                obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "ventas.isp_grabar_facturacion", Fact.ToFacturacion((int)operacion));

                if (obj != null)
                {
                    result = (string[])obj;
                    ResultFac= (string[])obj;
                    Msg = (string[])obj;
                }
                else
                {

                    result = new string[] { "F-00" };
                    Msg = new string[] { "F-00" };
                    ResultFac= new string[] { "F-00" };
                }

                /*fin codigo agregado*/

                if (result[0] == "0")
                {
                    for (int i = 0; i < DFact.dtbDetelle.Rows.Count; i++)
                    {

                        obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "ventas.ISP_GRBAR_DET_FACTURACION",
                            new object[] { 
                                    (int)operacion,
                                    int.Parse(DFact.dtbDetelle.Rows[i]["Item"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Precio"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Cantidad"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Imp_Bruto"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Dscto"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Subtotal"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["IGV"].ToString()),
                                    double.Parse(DFact.dtbDetelle.Rows[i]["Total"].ToString()),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["puntos"].ToString()),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["Alm"].ToString()),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["id_precios"].ToString()),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["id_unidad"].ToString()),
                                    DFact.dtbDetelle.Rows[i]["Codigo"].ToString(),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["id_lista"].ToString()),
                                    int.Parse(DFact.dtbDetelle.Rows[i]["Lista"].ToString()),
                                    0,//saldo inicial 1:sis es saldo inicial 0:no es saldo inicial
                                    "N",//genera Igv
                                    DFact.dtbDetelle.Rows[i]["Lote"].ToString(),
                                    1,//id_estado
                                    int.Parse( Msg[1].ToString()),//id_documento
                                    Msg[3],//_NUMDOC_FACTURACION
                                    DateTime.Parse(Msg[4].ToString()),//_FECHA_FACTURACION
                                    Msg[2],//_SERIE_FACTURACION
                                   "",//_ID_TRANZA  CCION
                                    "",//IDUSUARIO
                                    int.Parse(Msg[7].ToString()),//_ID_SUCURSAL
                                    int.Parse(Msg[5].ToString()),//_ID_DIRECCION_CLIENTE
                                    Msg[6].ToString()//IDCLIENTE
                            }
                            );
                        if (obj != null)
                        {
                            result = (string[])obj;
                        }
                        else
                        {

                            result = new string[] { "D-00" };
                        }
                        if (result[0] == "0")
                        {
                            res = true;
                        }
                        else
                        {
                            this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                            res = false;
                            break;
                        }
                    }
                    if (res == true)
                    {
                        if (Fact.op4 == 2)
                        {// si es una venta al contado que no genera ningun credito
                            object[] ObjectFac = new object[]
                            {
                                int.Parse( Msg[1].ToString()),//id_documento
                                Msg[2],//_SERIE_FACTURACION
                                Msg[3],//_NUMDOC_FACTURACION
                                DateTime.Parse(Msg[4].ToString()),//_FECHA_FACTURACION
                                int.Parse(Msg[5].ToString()),//_ID_DIRCCLIENTE
                                Msg[6],//_ID_CLIENTE
                                int.Parse(Msg[7].ToString()) //idsucursal de la facturacion
                            };
                            obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CAJA.ISP_GRABAR_MOVFACTURACION", Emov.ToObject((int)operacion, ObjectFac));

                            if (obj != null)
                            {
                                result = (string[])obj;
                                Msg = (string[])obj;
                            }
                            else
                            {

                                result = new string[] { "M-00" };
                                Msg = new string[] { "M-00" };
                            }
                            if (result[0] == "0")
                            {
                                if (Fact.op1 == 2)
                                {
                                    //object[] var_cred = new object[] { Ecred.Id_credito,Ecred.Id_sucursal_credito};
                                    //vinculamos el anticipo con la factura de una venta al contado
                                    Ecred.Numdoc_facturacion=    ResultFac[3].ToString();
                                    Ecred.Fecha_facturacion=    DateTime.Parse( ResultFac[4].ToString());
                                    Ecred.Serie_facturacion=    ResultFac[2].ToString();
                                    Ecred.Id_Sucursal=    int.Parse(ResultFac[7].ToString());
                                    Ecred.Id_DirCliente= int.Parse(ResultFac[5].ToString()); 
                                    Ecred.Id_Documento= int.Parse(ResultFac[1].ToString());
                                    Ecred.Id_Cliente = ResultFac[6].ToString();
                                    obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRBARFACT_CREDITO", Ecred.toLinkfacCredito((int)operacion));
                                    if (obj != null)
                                    {
                                        result = (string[])obj;
                                    }
                                    else
                                    {

                                        result = new string[] { "FC-00" };

                                    }
                                    if (result[0] == "0")
                                    {
                                        res = true;
                                    }
                                    else
                                    {
                                        this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                        res = false;
                                    }
                                }
                                else
                                {
                                    res = true;
                                }
                            }
                            else
                            {
                                this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                res = false;

                            }
                            // fin de movimiento de caja de una de un vanta al contado
                        }
                        else
                        {

                            if (Fact.op4 == 1) //si la venta es al credito registrando la cabecera de creditos
                            {
                                if (Fact.op1 == 1)// SI NO ES CON ANTICIPO ES GENERACION DE VETAS AL CREDITO
                                {

                                    obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRABAR_CAB_CREDITO", Ecred.toSaveCredito((int)operacion));
                                    if (obj != null)
                                    {
                                        result = (string[])obj;
                                        resCred = (string[])obj;

                                    }
                                    else
                                    {

                                        result = new string[] { "C-00" };
                                        resCred = new string[] { "C-00" };
                                    }

                                    // Console.Write("****** :" + result[0]);
                                    if (result[0] == "0")
                                    {
                                        //grabando las cuotas del credito
                                        obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRBARFACT_CREDITO", Ecred.toSavefacCredito((int)operacion, Msg, resCred));

                                        if (obj != null)
                                        {
                                            result = (string[])obj;
                                        }
                                        else
                                        {

                                            result = new string[] { "FC-00" };

                                        }
                                        if (result[0] == "0")
                                        {

                                            if (Ecred.Cuotas.Rows.Count > 0)
                                            {
                                                string ID_CUOTA = null, NRO_LETRA = "", ID_CREDITO = null, ID_SUCURSAL_CREDITO = null;
                                                for (int i = 0; i < Ecred.Cuotas.Rows.Count; i++)
                                                {
                                                    obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRABAR_CUOTA",
                                                        new object[] { 
                                                        (int)operacion,
                                                        "",//idcuota
                                                        resCred[1],//id_credito
                                                        Ecred.Cuotas.Rows[i]["Cuota"].ToString(),//_NRO_LETRA
                                                        DateTime.Parse( Ecred.Cuotas.Rows[i]["Fecha"].ToString()),//_FEC_VENCIMIENTO
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Capital"].ToString()),//_IMP_CAPITAL
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Intereses"].ToString()),//_IMP_INTERES
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Total_Couta"].ToString()),//_IMP_CUOTA
                                                        0,//_IMP_ADICIONAL
                                                        int.Parse(Ecred.Cuotas.Rows[i]["Dias"].ToString()),//_INTERVALO_DIAS
                                                        0,//_DIAS_GRACIA
                                                        0,//_IMP_MORA
                                                        null,//_FEC_PAGO
                                                        "S",//_GENERA_MORA
                                                        null,//_FEC_REFINANCIAMIENTO
                                                        null,//_FEC_EMISION
                                                        int.Parse(resCred[2]),//_ID_SUCURSAL_CREDITO
                                                        null,//_IDUSUARIO
                                                        1,//_ID_ESTADO
                                                });

                                                    if (obj != null)
                                                    {
                                                        result = (string[])obj;
                                                    }
                                                    else
                                                    {

                                                        result = new string[] { "CC-0" };
                                                    }
                                                    if (Ecred.Cuotas.Rows[i]["Cuota"].ToString().Trim().Equals("I-0"))
                                                    {
                                                        NRO_LETRA = Ecred.Cuotas.Rows[0]["Cuota"].ToString();
                                                        ID_CUOTA = result[1];
                                                        ID_CREDITO = result[2];
                                                        ID_SUCURSAL_CREDITO = result[3];
                                                    }
                                                    if (result[0] == "0")
                                                    {
                                                        res = true;
                                                    }
                                                    else
                                                    {
                                                        this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                        res = false;
                                                        break;
                                                    }
                                                }
                                                ///grabamos el movimiento de caja si existe una amortizacion desde creditos
                                                if (res == true)
                                                {


                                                    if (NRO_LETRA.Equals("I-0"))
                                                    {
                                                        object[] ObjectCuota = new object[]
                                                    {
                                                        ID_CUOTA,
                                                        ID_CREDITO,
                                                        ID_SUCURSAL_CREDITO
                                                    };

                                                        obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CAJA.ISP_GRABAR_MOVCUOTA", Emov.ToMovcajaCuota((int)operacion, ObjectCuota));

                                                        if (obj != null)
                                                        {
                                                            result = (string[])obj;
                                                        }
                                                        else
                                                        {

                                                            result = new string[] { "MC-00" };

                                                        }
                                                        if (result[0] == "0")
                                                        {
                                                            res = true;
                                                        }
                                                        else
                                                        {
                                                            this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                            res = false;
                                                        }
                                                    }
                                                }

                                            }
                                            else
                                            {
                                                this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                res = false;
                                            }
                                        }
                                        else
                                        {
                                            this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                            res = false;
                                        }
                                        // res = true;
                                    }
                                    else
                                    {
                                        this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                        res = false;

                                    }
                                }
                                else
                                {
                                    {
                                        //op_anticipo=2
                                        // vinculamos la cabecera del anticipo con la factura generada
                                        Ecred.Numdoc_facturacion = ResultFac[3].ToString();
                                        Ecred.Fecha_facturacion = DateTime.Parse(ResultFac[4].ToString());
                                        Ecred.Serie_facturacion = ResultFac[2].ToString();
                                        Ecred.Id_Sucursal = int.Parse(ResultFac[7].ToString());
                                        Ecred.Id_DirCliente = int.Parse(ResultFac[5].ToString());
                                        Ecred.Id_Documento = int.Parse(ResultFac[1].ToString());
                                        Ecred.Id_Cliente = ResultFac[6].ToString();
                                        obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRBARFACT_CREDITO", Ecred.toLinkfacCredito((int)operacion));
                                        if (obj != null)
                                        {
                                            result = (string[])obj;
                                        }
                                        else
                                        {

                                            result = new string[] { "FC-00" };

                                        }
                                        if (result[0] == "0")
                                        {
                                            if (Ecred.Cuotas.Rows.Count > 0)
                                            {
                                                string ID_CUOTA = null, NRO_LETRA = "", ID_CREDITO = null, ID_SUCURSAL_CREDITO = null;
                                                for (int i = 0; i < Ecred.Cuotas.Rows.Count; i++)
                                                {
                                                    obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CREDITOS.ISP_GRABAR_CUOTA",
                                                        new object[] { 
                                                        (int)operacion,
                                                        "",//idcuota
                                                        Ecred.Id_credito,//id_credito
                                                        Ecred.Cuotas.Rows[i]["Cuota"].ToString(),//_NRO_LETRA
                                                        DateTime.Parse( Ecred.Cuotas.Rows[i]["Fecha"].ToString()),//_FEC_VENCIMIENTO
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Capital"].ToString()),//_IMP_CAPITAL
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Intereses"].ToString()),//_IMP_INTERES
                                                        double.Parse(Ecred.Cuotas.Rows[i]["Total_Couta"].ToString()),//_IMP_CUOTA
                                                        0,//_IMP_ADICIONAL
                                                        int.Parse(Ecred.Cuotas.Rows[i]["Dias"].ToString()),//_INTERVALO_DIAS
                                                        0,//_DIAS_GRACIA
                                                        0,//_IMP_MORA
                                                        null,//_FEC_PAGO
                                                        "S",//_GENERA_MORA
                                                        null,//_FEC_REFINANCIAMIENTO
                                                        null,//_FEC_EMISION
                                                        Ecred.Id_sucursal_credito,//_ID_SUCURSAL_CREDITO
                                                        null,//_IDUSUARIO
                                                        1,//_ID_ESTADO
                                                });

                                                    if (obj != null)
                                                    {
                                                        result = (string[])obj;
                                                    }
                                                    else
                                                    {

                                                        result = new string[] { "CC-0" };
                                                    }
                                                    if (Ecred.Cuotas.Rows[i]["Cuota"].ToString().Trim().Equals("I-0"))
                                                    {
                                                        NRO_LETRA = Ecred.Cuotas.Rows[0]["Cuota"].ToString();
                                                        ID_CUOTA = result[1];
                                                        ID_CREDITO = result[2];
                                                        ID_SUCURSAL_CREDITO = result[3];
                                                    }
                                                    if (result[0] == "0")
                                                    {
                                                        res = true;
                                                    }
                                                    else
                                                    {
                                                        this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                        res = false;
                                                        break;
                                                    }
                                                }
                                                ///grabamos el movimiento de caja si existe una amortizacion desde creditos
                                                if (res == true)
                                                {


                                                    if (NRO_LETRA.Equals("I-0"))
                                                    {
                                                        object[] ObjectCuota = new object[]
                                                    {
                                                        ID_CUOTA,
                                                        ID_CREDITO,
                                                        ID_SUCURSAL_CREDITO
                                                    };

                                                        obj = PostgreSqlHelper.ExecuteScalar(this.CurrentConection, tran, "CAJA.ISP_GRABAR_MOVCUOTA", Emov.ToMovcajaCuota((int)operacion, ObjectCuota));

                                                        if (obj != null)
                                                        {
                                                            result = (string[])obj;
                                                        }
                                                        else
                                                        {

                                                            result = new string[] { "MC-00" };

                                                        }
                                                        if (result[0] == "0")
                                                        {
                                                            res = true;
                                                        }
                                                        else
                                                        {
                                                            this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                            res = false;
                                                        }
                                                    }
                                                }

                                            }
                                            else
                                            {
                                                this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                                res = false;
                                            }
                                            //vinculamos las cuotas a la cabecera del credito generado por el anticipo y 
                                           // res = true;
                                        }
                                        else
                                        {
                                            this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                                            res = false;
                                        }

                                    }
                                }

                            }
                           
                            
                       
                        //***************
                        }

                        
                       // res = true;
                    }
                    // res = true;
                }
                else
                {
                    this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                    res = false;
                }
                if (res == true)
                {
                    this.CurrentConection.CommintTransaction(tran);
                    Fact.opRet = 1;
                }
            }
            catch (NpgsqlException ex)
            {
                result[0] = ex.Message;
                Console.Write(ex.Message);
                this.CurrentConection.CancelarConexionTrans(this.CurrentConection.GetPostgreSqlConnection());
                Msg = new string[] { ex.Message };
                throw ex;
            }
            finally
            {
                this.CurrentConection.CloseConnection(con);
            }
            return result ;
        }
        #endregion
        #region Consultas
        public DataTable GetCabeceraFacturacion(ESistema obj)
        {
            DataTable dtb;
            NpgsqlConnection con = null;

            AccesoBD db = new AccesoBD();
            try
            {
                con = this.CurrentConection.GetPostgreSqlConnection();
                dtb = db.EjecutaModelView("VENTAS.V_LISTAR_CAB_FACTURACION", new object[] { obj.Condicion }, con);
            }
            catch (NpgsqlException ex)
            {
                this.CurrentConection.CloseConnection(con);
                Console.Write(string.Format("{0}/{1}", ex.Message, ex.Source));
                DataBaseUtils.PrintMessajeError(this.mensajeExecuteReader.Replace("#replace", " Los Productos"), ex);
                return null;
            }
            finally
            {
                this.CurrentConection.CloseConnection(con);
            }
            return dtb;
        }


        public DataTable GetCabeceraFacturacionVentas(ESistema obj)
        {
            DataTable dtb;
            NpgsqlConnection con = null;

            AccesoBD db = new AccesoBD();
            try
            {
                con = this.CurrentConection.GetPostgreSqlConnection();
                dtb = db.EjecutaModelView("VENTAS.v_listar_cabecera_facturacion_ventas", new object[] { obj.Condicion }, con);
            }
            catch (NpgsqlException ex)
            {
                this.CurrentConection.CloseConnection(con);
                Console.Write(string.Format("{0}/{1}", ex.Message, ex.Source));
                DataBaseUtils.PrintMessajeError(this.mensajeExecuteReader.Replace("#replace", " Los Productos"), ex);
                return null;
            }
            finally
            {
                this.CurrentConection.CloseConnection(con);
            }
            return dtb;
        }

        public DataTable GetDetaFacturacionVentas(ESistema obj)
        {
            DataTable dtb;
            NpgsqlConnection con = null;

            AccesoBD db = new AccesoBD();
            try
            {
                con = this.CurrentConection.GetPostgreSqlConnection();
                dtb = db.EjecutaModelView("VENTAS.V_LISTAR_DET_FACTURACION", new object[] { obj.Condicion }, con);
            }
            catch (NpgsqlException ex)
            {
                this.CurrentConection.CloseConnection(con);
                Console.Write(string.Format("{0}/{1}", ex.Message, ex.Source));
                DataBaseUtils.PrintMessajeError(this.mensajeExecuteReader.Replace("#replace", " Los Productos"), ex);
                return null;
            }
            finally
            {
                this.CurrentConection.CloseConnection(con);
            }
            return dtb;
        }
        #endregion
    }
}
